import {
  reactive,
  toRaw,
  computed,
  ref,
  shallowRef,
  onBeforeUnmount,
  nextTick
} from "vue";
import { message } from "@/utils/message";
import { HttpPagePar, ConditionalListType } from "@/utils/http/httpPagePar";
import {
  getPageDataApi,
  addApi,
  deleteApi,
  enableApi,
  updataApi
} from "@/api/contents";
import { anFileUpload } from "@/api/Common";
import {
  contentstitleVf,
  contentscontentVf,
  contentsphotoVf
} from "@/common/validator";
import { CmpHandleStateEnum, CmpGlobal } from "@/common/GlobalType";
import { contentsDto } from "@/Model/contents";
import type {
  FormRules,
  UploadProps,
  UploadRequestHandler,
  FormInstance
} from "element-plus";
import type { PaginationProps } from "@pureadmin/table";
import { IsHttpImg, imgType } from "@/utils/imgtool";

type CmpGlobalType = CmpGlobal;
type SearchFormType = {
  title: string;
  ifdisable: string;
};

/**
 * 观看平台hook
 * @returns columns 表格头部列 {obiect} onSearch 表格搜索事件 {obiect}
 */
export function useWatch() {
  const mode = "default";
  // 编辑器实例，必须用 shallowRef
  const editorRef = shallowRef();

  const toolbarConfig: any = { excludeKeys: "fullScreen" };
  const editorConfig = {
    placeholder: "请输入内容...",
    readOnly: false,
    MENU_CONF: {}
  };
  editorConfig.MENU_CONF["uploadImage"] = {
    // 上传图片的配置
    // 单个文件的最大体积限制，默认为 2M
    maxFileSize: 1 * 1024 * 1024, // 1
    // 超时时间，默认为 10 秒
    timeout: 10 * 1000, // 10 秒
    // 小于该值就插入 base64 格式（而不上传），默认为 0
    //base64LimitSize: 100 * 1024, // 100kb
    // 自定义上传
    async customUpload(file: File, insertFn: any) {
      anFileUpload({ file: file })
        .then(res => {
          if (res.code === 1) {
            const imageUrl = IsHttpImg(res.data.filepath);
            insertFn(imageUrl, res.data.filename, imageUrl);
          } else {
            message("图片上传失败，请查看日志", { type: "error" });
            console.log(res);
          }
        })
        .catch(err => {
          message("图片上传失败，请查看日志", { type: "error" });
          console.log(err);
        });
    }
  };

  // 组件销毁时，也及时销毁编辑器
  onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
  });

  const handleCreated = editor => {
    editorRef.value = editor; // 记录 editor 实例，重要！
  };
  /** 搜索区树形选择框ref */
  const searchtree = ref(null);
  /** 表格头部列 */
  const columns: TableColumnList = [
    {
      type: "selection",
      width: 55,
      align: "left",
      hide: ({ checkList }) => !checkList.includes("勾选列")
    },
    {
      label: "序号",
      type: "index",
      minWidth: 70,
      hide: ({ checkList }) => !checkList.includes("序号列")
    },
    {
      label: "标题",
      prop: "title"
    },
    {
      label: "是否置顶",
      prop: "iftop",
      cellRenderer: ({ row, props }) => (
        <el-tag
          size={props.size}
          type={row.iftop === 1 ? "success" : "danger"}
          effect="plain"
        >
          {row.iftop === 1 ? "是" : "否"}
        </el-tag>
      )
    },
    {
      label: "是否禁用",
      prop: "ifdisable",
      cellRenderer: ({ row, props }) => (
        <el-tag
          size={props.size}
          type={row.ifdisable === 1 ? "success" : "danger"}
          effect="plain"
        >
          {row.ifdisable === 1 ? "启用" : "禁用"}
        </el-tag>
      )
    },
    {
      label: "创建人",
      prop: "createdUsers.name"
    },
    {
      label: "更新人",
      prop: "updatedUsers.name"
    },
    {
      label: "最近更新时间",
      prop: "updatedtime"
    },
    {
      label: "操作",
      slot: "operation"
    }
  ];
  /** 组件需要全局使用的变量 */
  const cmpglobal = reactive<CmpGlobalType>({
    dialogVisible: false,
    cmpHandleState: CmpHandleStateEnum.View,
    ids: [],
    tableTitle: "文章列表"
  });
  /** 更新或添加表单 */
  const addorupdataform = reactive<contentsDto>({
    id: 0,
    ifdisable: 1,
    title: "",
    content: "",
    photo: "",
    imageUrl: "",
    iftop: 0
  });
  /** 表单验证对象 */
  const rules = reactive<FormRules>({
    title: contentstitleVf,
    content: contentscontentVf,
    photo: contentsphotoVf
  });
  /** 搜索框表单 */
  const searchform = reactive<SearchFormType>({
    title: "",
    ifdisable: "1"
  });
  /** 表格绑定数据对象 */
  const tabledata: any = reactive({
    data: []
  });
  /** 分页配置 */
  const pagination = reactive<PaginationProps>({
    pageSize: 10,
    currentPage: 1,
    pageSizes: [10, 15, 20],
    total: 0,
    align: "center",
    background: true,
    small: false
  });
  /** dialog标题 */
  const dialogtitle = computed(() => {
    let res = "";
    switch (cmpglobal.cmpHandleState) {
      case CmpHandleStateEnum.Add:
        res = "新增";
        break;
      case CmpHandleStateEnum.Updata:
        res = "修改";
        break;
      default:
        res = "查看";
        break;
    }
    return res;
  });
  /** 表单输入框是否禁用 */
  const ifDisabledForm = computed(() => {
    if (cmpglobal.cmpHandleState === CmpHandleStateEnum.View) {
      return true;
    } else {
      return false;
    }
  });
  /** 表单输入框是否禁用 */
  const ifDisabledFormResetBut = computed(() => {
    if (cmpglobal.cmpHandleState === CmpHandleStateEnum.Add) {
      return false;
    } else {
      return true;
    }
  });

  /** api数据请求体 */
  const httpPagePar = new HttpPagePar();

  /**
   * 向服务器请求表格数据
   */
  function getPageData() {
    httpPagePar.pageNum = pagination.currentPage;
    httpPagePar.pageSize = pagination.pageSize;
    const conditionallist: ConditionalListType[] = [];
    if (searchform.title !== "") {
      const item: ConditionalListType = {
        key: 0,
        value: {
          fieldName: "title",
          fieldValue: searchform.title,
          cSharpTypeName: "string",
          conditionalType: 1
        }
      };
      conditionallist.push(item);
    }
    if (searchform.ifdisable === "0" || searchform.ifdisable === "1") {
      const item: ConditionalListType = {
        key: 0,
        value: {
          fieldName: "ifdisable",
          fieldValue: searchform.ifdisable,
          cSharpTypeName: "long",
          conditionalType: 0
        }
      };
      conditionallist.push(item);
    }
    if (conditionallist.length > 0) {
      httpPagePar.conditionalList = conditionallist;
    } else {
      httpPagePar.conditionalList = [];
    }
    httpPagePar.orderBys = ["id desc"];

    getPageDataApi(httpPagePar)
      .then(res => {
        if (res.code === 1) {
          tabledata.data = res.data.data;
          pagination.total = res.data.total;
        } else {
          message(res.msg, { type: "error" });
          tabledata.data = [];
          pagination.total = 0;
        }
      })
      .catch(err => {
        message(`获取表格数据失败:${err}`, { type: "error" });
        console.log(err);
      });
  }

  /**
   * 搜索事件
   */
  const clickSearch = () => {
    pagination.currentPage = 1;
    getPageData();
  };
  /**
   * 分页控件选择显示多少条数据事件
   */
  function onSizeChange(val) {
    pagination.pageSize = val;
    //重新获取数据
    getPageData();
  }
  /**
   * 分页控件选择页码事件
   */
  function onCurrentChange(val) {
    pagination.currentPage = val;
    //重新获取数据
    getPageData();
  }

  /**
   * 表格的刷新事件
   */
  function onSearch() {
    //重新获取数据
    getPageData();
  }
  /**
   * 表格查看事件
   * @param row 选中数据
   */
  function handleView(row) {
    cmpglobal.cmpHandleState = CmpHandleStateEnum.View;
    cmpglobal.dialogVisible = true;
    SetFormData(row);
  }

  /**
   * 表格修改事件
   * @param row 选中数据
   */
  function handleUpdate(row) {
    cmpglobal.cmpHandleState = CmpHandleStateEnum.Updata;
    cmpglobal.dialogVisible = true;
    SetFormData(row);
  }
  /**
   * 网络请求禁用数据
   * @param params id数组
   */
  function Delete(params: number[]) {
    deleteApi({ ids: params })
      .then(res => {
        if (res.code === 1) {
          message(res.msg, { type: "success" });
          //更新数据
          getPageData();
        } else {
          message(res.msg, { type: "error" });
        }
        cmpglobal.ids = [];
      })
      .catch(err => {
        cmpglobal.ids = [];
        message(`禁用失败:${err}`, { type: "error" });
        console.log(err);
      });
  }
  /**
   * 网络请求禁用数据
   * @param params id数组
   */
  function Enable(params: number[]) {
    enableApi({ ids: params })
      .then(res => {
        if (res.code === 1) {
          message(res.msg, { type: "success" });
          //更新数据
          getPageData();
        } else {
          message(res.msg, { type: "error" });
        }
        cmpglobal.ids = [];
      })
      .catch(err => {
        cmpglobal.ids = [];
        message(`禁用失败:${err}`, { type: "error" });
        console.log(err);
      });
  }
  /**
   * 表格删除事件
   * @param row 选中数据
   */
  function handleDelete(row) {
    Delete([row.id]);
  }
  /**
   * 表格启用事件
   * @param row 选中数据
   */
  function handleEnable(row) {
    Enable([row.id]);
  }
  /**
   * 批量删除
   */
  function handleBatchDelete() {
    if (cmpglobal.ids.length <= 0) {
      message("请选择需要禁用的数据", { type: "error" });
    } else {
      Delete(toRaw(cmpglobal.ids));
    }
  }
  /**
   * 批量启用
   */
  function handleBatchEnable() {
    if (cmpglobal.ids.length <= 0) {
      message("请选择需要禁用的数据", { type: "error" });
    } else {
      Enable(toRaw(cmpglobal.ids));
    }
  }
  /**
   * 表格选择列的事件
   * @param val 选中数据
   */
  function handleSelectionChange(val) {
    if (val.length > 0) {
      const selectids: number[] = [];
      val.forEach(function (item) {
        selectids.push(item.id);
      });
      cmpglobal.ids = selectids;
    }
  }
  /**
   * 文件上传成功时的钩子
   */
  const handleAvatarSuccess: UploadProps["onSuccess"] = (
    _response,
    _uploadFile
  ) => {
    //response 是上传成功服务器返回的数据
  };
  /**
   * 文件上传失败时的钩子
   */
  const handleAvatarError: UploadProps["onError"] = (
    _response,
    _uploadFile
  ) => {
    //response 是上传成功服务器返回的数据
  };
  /**
   * 上传文件之前的钩子，参数为上传的文件， 若返回false或者返回 Promise 且被 reject，则停止上传。
   */
  const beforeAvatarUpload: UploadProps["beforeUpload"] = rawFile => {
    const fileType = imgType;
    if (!fileType.includes(rawFile.type)) {
      message("只能上传图片格式", { type: "error" });
      return false;
    }
    if (rawFile.size / 1024 / 1024 > 1) {
      message("不能上传大于1M的图片", { type: "error" });
      return false;
    }
    return true;
  };
  /**
   * 上传文件文件函数
   */
  function uploadFile(item): UploadRequestHandler {
    anFileUpload({ file: item.file })
      .then(res => {
        if (res.code === 1) {
          addorupdataform.photo = res.data.filepath;
          addorupdataform.imageUrl = IsHttpImg(res.data.filepath);
          item.onSuccess(res);
        } else {
          message(res.msg, { type: "error" });
          item.onError(res);
        }
      })
      .catch(err => {
        message("图片上传失败，请查看日志", { type: "error" });
        item.onError(err);
        console.log(err);
      });
    return;
  }
  /**
   * 重置搜索表单
   */
  function resetSearchForm() {
    searchform.title = "";
    searchform.ifdisable = "";
    getPageData();
  }
  /**
   * 重置表单
   */
  function resetAddOrUpdataForm(_formEl: FormInstance | undefined) {
    addorupdataform.id = 0;
    addorupdataform.ifdisable = 1;
    addorupdataform.title = null;
    nextTick(() => {
      // editorRef.value.focus();
      addorupdataform.content = "";
    });
    addorupdataform.photo = null;
    addorupdataform.imageUrl = null;
    addorupdataform.iftop = 0;
    // if (!formEl) return;
    // formEl.resetFields();
  }
  /**
   * 设置表单数据
   * @param row 行数据
   */
  function SetFormData(row: any) {
    addorupdataform.id = row.id;
    addorupdataform.ifdisable = row.ifdisable;
    addorupdataform.title = row.title;
    nextTick(() => {
      // editorRef.value.focus();
      addorupdataform.content = row.content;
    });

    addorupdataform.photo = row.photo;
    addorupdataform.imageUrl = IsHttpImg(row.photo);
    addorupdataform.iftop = row.iftop;
  }
  /**
   * 点击添加事件
   */
  function addClick(formEl: FormInstance | undefined) {
    cmpglobal.dialogVisible = true;
    cmpglobal.cmpHandleState = CmpHandleStateEnum.Add;
    resetAddOrUpdataForm(formEl);
  }
  /**
   * 保存按键事件
   */
  const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, _fields) => {
      if (valid) {
        if (cmpglobal.cmpHandleState === CmpHandleStateEnum.Add) {
          //新增
          addApi(toRaw(addorupdataform))
            .then(res => {
              if (res.code === 1) {
                message(res.msg, { type: "success" });
                //重置表单
                resetAddOrUpdataForm(formEl);
                //更新数据
                getPageData();
              } else {
                message(res.msg, { type: "error" });
              }
            })
            .catch(err => {
              message("添加失败:" + err, { type: "error" });
            });
        }
        if (cmpglobal.cmpHandleState === CmpHandleStateEnum.Updata) {
          //更新
          updataApi(toRaw(addorupdataform))
            .then(res => {
              if (res.code === 1) {
                message(res.msg, { type: "success" });
                //重置表单
                resetAddOrUpdataForm(formEl);
                //更新数据
                getPageData();
                cmpglobal.dialogVisible = false;
              } else {
                message(res.msg, { type: "error" });
              }
            })
            .catch(err => {
              message("更新失败:" + err, { type: "error" });
              resetAddOrUpdataForm(formEl);
              cmpglobal.dialogVisible = false;
            });
        }
      } else {
        // console.log("表单验证失败", fields);
        message("请输入必填项", { type: "error" });
      }
    });
  };
  /**
   * dialog对话框关闭回调函数
   */
  function dialogClose() {}
  /**
   * dialog对话框打开回调函数
   */
  function dialogOpen() {
    //获取所有分类的树形数据
    //getClassifyTreeData();
  }
  return {
    columns,
    onSearch,
    searchform,
    tabledata,
    getPageData,
    handleView,
    handleUpdate,
    handleDelete,
    handleSelectionChange,
    handleBatchDelete,
    handleBatchEnable,
    cmpglobal,
    dialogtitle,
    addorupdataform,
    handleAvatarSuccess,
    beforeAvatarUpload,
    handleAvatarError,
    uploadFile,
    resetSearchForm,
    resetAddOrUpdataForm,
    addClick,
    rules,
    submitForm,
    pagination,
    onSizeChange,
    onCurrentChange,
    clickSearch,
    dialogClose,
    handleEnable,
    ifDisabledForm,
    ifDisabledFormResetBut,
    dialogOpen,
    searchtree,
    editorRef,
    toolbarConfig,
    mode,
    editorConfig,
    handleCreated
  };
}
